<template>
  <div>
    <el-card>
      <div class="header_class">
        <el-input v-model="queryInfo.name" placeholder="请输入内容" class="input-with-select" clearable
                  style="width: 300px" @clear="getUserList()">
          <el-button slot="append" icon="el-icon-search" @click="handleSearch"/>
        </el-input>
        <el-button type="primary" icon="el-icon-plus" v-if="hasPerm('user_add_scopes')" style="margin-left: 20px"
                   @click="handleAddUser">新增
        </el-button>
        <el-button type="primary" icon="el-icon-upload2" style="margin-left: 20px" @click="handleExportUser">导出
        </el-button>
        <el-upload
          class="upload-demo"
          ref="upload"
          action="dummy-action"
          :show-file-list="false" :before-upload="handleImportUser">
          <el-button type="primary" icon="el-icon-download" style="margin-left: 20px">导入</el-button>
        </el-upload>
      </div>

      <el-table :data="userList" style="width: 100%; margin-top: 20px" border @selection-change="selectionChange">
        <el-table-column type="selection" width="50px"/>
        <el-table-column label="序号" type="index" align="center" width="50px"/>
        <el-table-column label="用户名" prop="name" align="center"/>
        <el-table-column label="昵称" prop="nick_name" align="center"/>
        <el-table-column label="邮箱" prop="email" align="center"/>
        <el-table-column label="电话" prop="phone" align="center"/>
        <el-table-column label="角色名称" prop="role" align="center">
          <template #default="scope">
            <el-tag v-for="item in scope.row.role" :key="item.id" style="margin-right: 10px">{{ item.name }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200px">
          <template v-slot="scope">
            <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(scope.row)"/>
            <el-button type="success" icon="el-icon-refresh" circle @click="handleReset(scope.row)"/>
            <el-button type="danger" icon="el-icon-delete" circle @click="handleDel(scope.row)"/>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination :current-page="queryInfo.page" :page-sizes="[5, 10, 20]" :page-size="queryInfo.size"
                     layout="total, sizes, prev, pager, next, jumper" :total="total" style="margin-top: 20px"
                     @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
    </el-card>

    <!--新增用户弹框-->
    <el-dialog title="新增用户" :visible.sync="addVisible" width="30%" :before-close="handleAddClose">
      <el-form ref="addUserForm" :model="addUserForm" :rules="addUserRules" label-width="80px" class="addUserForm">
        <el-form-item label="账号" prop="name">
          <el-input v-model="addUserForm.name"/>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="addUserForm.password" type="password"/>
        </el-form-item>
        <el-form-item label="确认密码" prop="confirm_password">
          <el-input v-model="addUserForm.confirm_password" type="password"/>
        </el-form-item>
        <el-form-item label="昵称" prop="nick_name">
          <el-input v-model="addUserForm.nick_name"/>
        </el-form-item>
        <el-form-item label="电话" prop="phone">
          <el-input v-model="addUserForm.phone"/>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="addUserForm.email"/>
        </el-form-item>
        <el-form-item label="角色">
          <el-select v-model="addUserForm.role" placeholder="请选择角色名称">
            <el-option v-for="role in roleList" :key="role.id" :label="role.name" :value="role.id"/>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleAddClose">取 消</el-button>
        <el-button type="primary" @click="handleAddUserSubmit">确 定</el-button>
      </span>
    </el-dialog>

    <!--编辑用户弹框-->
    <el-dialog title="编辑用户" :visible.sync="editVisible" width="30%" :before-close="handleEditClose">
      <el-form ref="editUserForm" :model="editUserForm" :rules="editUserRules" label-width="80px" class="editUserForm">
        <el-form-item label="账号" prop="name">
          <el-input v-model="editUserForm.name" disabled/>
        </el-form-item>
        <el-form-item label="昵称" prop="nick_name">
          <el-input v-model="editUserForm.nick_name"/>
        </el-form-item>
        <el-form-item label="电话" prop="phone">
          <el-input v-model="editUserForm.phone"/>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="editUserForm.email"/>
        </el-form-item>
        <el-form-item label="角色">
          <el-select v-model="editUserForm.role" placeholder="请选择角色名称">
            <el-option v-for="role in roleList" :key="role.id" :label="role.name" :value="role.id"/>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleEditClose">取 消</el-button>
        <el-button type="primary" @click="handleEditUserSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {addUser, delUser, exportUser, getUser, resetUser, updateUser, uploadUser, userList} from '@/api/user'
import {role} from '@/api/role'
import {emailCheck, phoneCheck} from '@/utils/validate'
import {hasPermissions} from "@/hasPermissions";

export default {
  name: 'UserList',
  components: {},
  data() {
    const checkPassword = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请再次输入密码！'))
      } else if (value !== this.addUserForm.password) {
        callback(new Error('两次输入密码不一致!'))
      } else {
        callback()
      }
    }
    const validatePhone = (rule, value, callback) => {
      if (!phoneCheck(value)) {
        callback(new Error('请输入正确格式的电话号码！'))
      } else {
        callback()
      }
    }
    const validateEmail = (rule, value, callback) => {
      if (!emailCheck(value)) {
        callback(new Error('请输入正确格式的邮箱！'))
      } else {
        callback()
      }
    }
    return {
      addVisible: false, // 新增用户弹框
      editVisible: false, // 编辑用户弹框
      queryInfo: {
        name: '',
        size: 5,
        page: 1
      },
      addUserForm: {
        name: '',
        confirm_password: '',
        password: '',
        nick_name: '',
        phone: '',
        email: '',
        role: ''
      },
      editUserForm: {
        name: '',
        nick_name: '',
        phone: '',
        email: '',
        role_name: ''
      },
      addUserRules: {
        name: [
          {required: true, message: '请输入用户账号！', trigger: 'blur'},
          {
            min: 3,
            max: 10,
            message: '长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        password: [
          {required: true, message: '请再次输入密码！', trigger: 'blur'},
          {
            min: 3,
            max: 10,
            message: '长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        confirm_password: [
          {required: true, message: '请确认密码！', trigger: 'blur'},
          {validator: checkPassword, trigger: 'blur'}
        ],
        phone: [{validator: validatePhone, trigger: 'blur'}],
        email: [{validator: validateEmail, trigger: 'blur'}]
      },
      editUserRules: {
        name: [
          {required: true, message: '请输入用户账号！', trigger: 'blur'},
          {
            min: 3,
            max: 10,
            message: '长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        phone: [{validator: validatePhone, trigger: 'blur'}],
        email: [{validator: validateEmail, trigger: 'blur'}]
      },
      page: 1, // 当前页
      total: 0,
      userList: [],
      roleList: [],
      selectChecked: [] // 被选中的table列表
    }
  },
  computed: {},
  mounted() {
    this.getUserList()
    this.getRoleList()
  },
  methods: {
    hasPermissions,
    // 获取用户列表
    async getUserList() {
      try {
        const res = await userList(this.queryInfo)
        if (res.code !== 200) return this.$message.error(res.msg)
        this.userList = res.data.data
        this.total = res.data.total
      } catch (error) {
        console.error('Failed to fetch user list:', error)
      }
    },
    // 查询按钮
    handleSearch() {
      console.log(111)
      this.getUserList()
    },
    // 用户新增按钮
    handleAddUser() {
      this.addVisible = true
    },
    // 用户新增弹框确定按钮
    async handleAddUserSubmit() {
      const res = await addUser(JSON.stringify(this.addUserForm))
      if (res.code !== 200) return this.$message.error(res.msg)
      this.$message.success('新增成功！')
      this.$refs.addUserForm.resetFields()
      this.addVisible = false
      this.getUserList()
    },
    // 导出接口
    async handleExportUser() {
      try {
        // 调用导出的接口
        const res = await exportUser({ids: this.selectChecked.join(',')})
        // 处理导出的Excel文件

        const blob = new Blob([res], {type: 'application/vnd.ms-excel;charset=utf-8'});
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');

        link.href = url;
        link.setAttribute('download', '用户导出表');
        document.body.appendChild(link);
        link.click();

        document.body.removeChild(link);
        window.URL.revokeObjectURL(url);
      } catch (error) {
        console.error(error)
      }
    },
    // 用户编辑操作
    async handleEdit(row) {
      const res = await getUser(row.id)
      if (res.code !== 200) return this.$message.error(res.msg)
      this.editUserForm = res.data
      this.editVisible = true
    },
    // 用户编辑弹框确定按钮
    async handleEditUserSubmit() {
      const res = await updateUser(JSON.stringify(this.editUserForm))
      if (res.code !== 200) return this.$message.error(res.msg)
      this.$message.success('编辑成功！')
      this.editVisible = false
      this.getUserList()
    },
    // 用户重置密码功能
    async handleReset(row) {
      const res = await this.$confirm('此操作将重置用户密码, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(e => (e))
      if (res === 'cancel') return this.$message.info('取消重置！')
      const result = await resetUser(row.id)
      if (result.code !== 200) return this.$message.error('重置密码失败！')
      this.$message.success(result.msg)
    },
    // 用户删除
    async handleDel(row) {
      const res = await this.$confirm(`此操作将删除${row.name}用户, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(e => (e))
      if (res === 'cancel') return this.$message.info('取消删除！')
      const result = await delUser(row.id)
      if (result.code !== 200) return this.$message.error('删除用户失败！')
      this.$message.success('删除用户成功！')
      this.getUserList()
    },
    // 每页条数变化回调
    handleSizeChange(val) {
      this.queryInfo.size = val
      this.getUserList()
    },
    // 页码发生变化回调
    handleCurrentChange(val) {
      this.queryInfo.page = val
      this.getUserList()
    },
    // 新增弹框关闭回调
    handleAddClose() {
      this.addVisible = false
      this.$refs.addUserForm.resetFields()
    },
    // 编辑弹框关闭回调
    handleEditClose() {
      this.editVisible = false
      this.$refs.editUserForm.resetFields()
    },
    // 获取所有角色
    async getRoleList() {
      const res = await role()
      if (res.code !== 200) return this.$message.error(res.msg)
      this.roleList = res.data.items
    },
    // table选择项变化的回调
    selectionChange(selection) {
      selection.forEach(item =>
        this.selectChecked.push(item.id)
      )
    },
    // 导入的回调
    async handleImportUser(file) {
      if (!file.name.endsWith('.xlsx')) return this.$message.error('请上传Excel文件！')
      if (file.size > 1024 * 1024 * 5) return this.$message.error('文件大小不能超过5MB！')
      const res = await uploadUser(file)
      if (res.code !== 200) return this.$message.error('导入失败！')
      this.$message.success('导入成功！')
      this.getUserList()
    }
  },
  watch: {
    queryInfo: function () {
      this.getUserList()
    }
  }
}
</script>

<style scoped lang="scss">
.header_class {
  display: flex;
}
</style>
